package com.pablito.webapp.action.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.opensymphony.xwork2.Preparable;
import com.pablito.model.User;
import com.pablito.service.UserManager;
import com.pablito.service.exception.UserException;
import com.pablito.service.exception.UserException.UserExceptionCause;
import com.pablito.webapp.action.BaseAction;
import com.pablito.webapp.security.LoginHandler;

public class CredentialsExpiredAction extends BaseAction implements Preparable {
	
	private static final String LOGOUT = "logout";
	@Autowired
	private UserManager userManager;
	
	private static final long serialVersionUID = -6821511610168292245L;
	private User user;
	
	@Override
	public String execute() throws Exception {
		String result = SUCCESS;
		try {
			user = getUserFromSession();
			user.setPassword(null);
		} catch (UsernameNotFoundException unfe) {
			result = LOGOUT;
		}
		
		return result;
	}
	
	public String renewCredentials() {
		String result;
		try {
			user.setCredentialsExpired(false);
			userManager.renewCredentials(user);
			getRequest().getSession().setAttribute("loginMsg", "credentialsExpired.renewedMsg");
			result = SUCCESS;
		} catch (UserException ue) {
			String errorMsg; 
			if (ue.getCause().getMessage().equals(UserExceptionCause.RENEW_CREDENTIALS_EXCEPTION.getCode())) {
				errorMsg = getText(getCustomExceptionMessageKey(ue));
			} else {
				errorMsg = getText("errors.unexpected");
			}
			addActionError(errorMsg);
			result = INPUT;
		} catch (Exception e) {
			log.error(e.getMessage());
			addActionError(getText("errors.unexpected"));
			result = INPUT;
		} finally {
			if (!getActionErrors().isEmpty()) {
				user.setPassword(null);
				user.setConfirmPassword(null);
			}
		}
		
		return result;
	}
	
	public String cancel() {
		return LOGOUT;
	}

	/**
	 * Obtiene el usuario usando el nombre guardado en la sesión por {@link LoginHandler}. 
	 * Luego borra el atributo de sesión por seguridad.
	 * @return {@link User} usuario cuyas credenciales han expirado.
	 * @throws UsernameNotFoundException si no existe el usuario.
	 */
	private User getUserFromSession() throws UsernameNotFoundException {
		String username = (String) getRequest().getSession().getAttribute(LoginHandler.USERNAME_SESSION_KEY);
		getRequest().getSession().removeAttribute(LoginHandler.USERNAME_SESSION_KEY);
		return userManager.getUserByUsername(username);
	}
	
	public void prepare() throws Exception {
		if (getRequest().getMethod().equalsIgnoreCase("post") && (!"".equals(getRequest().getParameter("user.id")))) {
            user = userManager.getUser(getRequest().getParameter("user.id"));
        }
	}
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
}
